COM Event Handling

Clients subscribe to wrapper instance events through a process called advising. The wrapper object defines an outgoing source interface (event interface) containing the event methods, and the client implements that interface. During advising, the client passes a reference to its event interface to the wrapper. When an event occurs within the wrapper, it fires the event to the client by calling the appropriate event method on the client’s event interface.

Note: ActiveX controls are obsolete.

ActiveX controls fire events in the classical way via an outgoing source interface. The Export Bridge ActiveX wrapper controls define the outgoing source interface_DIDLWrapperEvents, as described below. Any client that wants to receive the events must subscribe to events by calling the wrapper object’s IConnectionPoint::Advise() method. Once advised, the client unsubscribes to events by calling IConnectionPoint::Unadvise().

HRESULT Advise ([in] IUnknown* pUnk, [out,retval] DWORD* pdwCookie);

HRESULT Unadvise ([in] DWORD dwCookie);

The client implements the _DIDLWrapperEvents interface and calls the wrapper object’s Advise() method with its _DIDLWrapperEvents interface reference, and receives a cookie for that connection. When the clients wants to disconnect, the client calls Unadvise() with the connection cookie.

In the classical sense, only ActiveX controls fire events, which are typically UI events. However, a client using an Export Bridge COM wrapper object may be interested in IDL output and notification. So, we carry the concept of firing events over onto COM objects. Clients of COM wrapper objects can receive events by advising to the same outgoing source interface in the same way that clients advise for events on the ActiveX wrapper controls.

Mouse and Keyboard Events in COM Export Objects

For UI events generated by ActiveX wrapper object, the client receives the events first before IDL receives them. The client then has the option to “eat” the event and prevent IDL from ever seeing the event. Each UI event has a ForwardToIdl parameter, which is initially set to TRUE (1). If the event handler in the client code clears the value to FALSE (0), then the wrapper does not forward the event to IDL.

Note: ActiveX controls are obsolete.

For a COM example that passes keyboard events to IDL, see COM IDLitWindow Surface Manipulation.

The event interface is defined below and uses the following values. The mouse

Button parameter can have any of the following values ORed together:

IDLBML_MBUTTON_LEFT 0x1,

IDLBML_MBUTTON_RIGHT 0x2,

IDLBML_MBUTTON_MIDDLE 0x4,

The KeyState parameter can have any of the following values ORed together:

IDLBML_KEYSTATE_SHIFT 0x1,

IDLBML_KEYSTATE_CTRL 0x2,

IDLBML_KEYSTATE_CAPSLOCK 0x4,

IDLBML_KEYSTATE_ALT 0x8,

For the KeyCode parameters, if the key pressed is an ASCII character, then KeyCode is the ASCII value; otherwise it is one of these values:

IDLBML_KEYBOARD_EVENT_SHIFT 1

IDLBML_KEYBOARD_EVENT_CONTROL 2

IDLBML_KEYBOARD_EVENT_CAPSLOCK 3

IDLBML_KEYBOARD_EVENT_ALT 4

IDLBML_KEYBOARD_EVENT_LEFT 5

IDLBML_KEYBOARD_EVENT_RIGHT 6

IDLBML_KEYBOARD_EVENT_UP 7

IDLBML_KEYBOARD_EVENT_DOWN 8

IDLBML_KEYBOARD_EVENT_PAGE_UP 9

IDLBML_KEYBOARD_EVENT_PAGE_DOWN 10

IDLBML_KEYBOARD_EVENT_HOME 11

IDLBML_KEYBOARD_EVENT_END 12

IDLBML_KEYBOARD_EVENT_DEL 127 // isASCII is set to 1 when this code is given

Note: The constants above are defined in the typelib information contained within each wrapper object and are used with the _DIDLWrapperEvents interface defined below.

dispinterface _DIDLWrapperEvents

{

HRESULT OnMouseDown (long Button, long KeyState, long x, long y, [in,out]long* ForwardToIdl);

HRESULT OnMouseUp (long Button, long KeyState, long x, long y, [in,out]long* ForwardToIdl);

HRESULT OnMouseMove (long Button, long KeyState, long x, long y, [in,out]long* ForwardToIdl);

HRESULT OnMouseWheel (long KeyState, long WheelDelta, long x, long y, [in,out]long* ForwardToIdl);

HRESULT OnMouseDoubleClick (long Button, long KeyState, long x, long y, [in,out]long* ForwardToIdl);

HRESULT OnMouseEnter (void); HRESULT OnMouseExit (void);

HRESULT OnKeyDown (long KeyCode, long KeyState, [in,out]long* ForwardToIdl);

HRESULT OnKeyUp (long KeyCode, long KeyState, [in,out]long* ForwardToIdl);

HRESULT OnSize (long width, long height, [in,out]long* ForwardToIdl);

HRESULT OnIDLNotify (BSTR bstr1, BSTR bstr2);

HRESULT OnIDLOutput (BSTR bstrOutput);

};

Note: For the OnMouseWheel event, the value of WheelDelta is a positive or negative value that indicates the amount that the wheel was rotated forward or backward, e.g. +/- 1, +/- 2, etc.

Note: Since the COM wrapper uses the same event interface, only the OnIDLNotify and OnIDLOutput events will be fired to subscribers of COM “events.” The UI events in the _DIDLWrapperEvents interface have no meaning in a nondrawable COM wrapper context, and therefore will not be fired to the client.